#include "window_win32.h"
#include "renderer_opengl.h"
#include "opengl_context_pool_win32.h"
#include "jobs.h"
#include "state_stack.h"

using namespace krryn::system;
using namespace krryn::core;

#define WINDOW_CLASS "__KRRYN__"

static LRESULT CALLBACK callback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
	if(message == WM_CLOSE || (message == WM_KEYDOWN && wParam == VK_ESCAPE))
		state_stack::get_instance().flush();
	return DefWindowProc(hWnd, message, wParam, lParam);
}

window_win32::window_win32(const std::string &a_Title, unsigned int a_Width, 
						   unsigned int a_Height){
	WNDCLASS wc = {0};
	wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
	wc.hInstance = GetModuleHandle(0);
	wc.lpfnWndProc = callback;
	wc.lpszClassName = TEXT(WINDOW_CLASS);
	RegisterClass(&wc);
	hWnd = CreateWindow(wc.lpszClassName, TEXT(a_Title.c_str()), 
		WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, a_Width, a_Height, 
		NULL, NULL, wc.hInstance, NULL);
	ShowWindow(hWnd, SW_SHOWNORMAL);
	UpdateWindow(hWnd);
	BringWindowToTop(hWnd);
}

renderer* window_win32::create_renderer(
	const std::string &a_Subsystem, 
	const job_manager &a_Manager)
{

	// find a way to create contexts form opengl_context_win32

	return new renderer_opengl(
		new opengl_context_pool_win32(
			hWnd, a_Manager.get_number_of_threads()));
}

window_win32::~window_win32(){
	DestroyWindow(hWnd);
}

void window_win32::update(){
	MSG msg;
	if(PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE) > 0){
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
}

#undef WINDOW_CLASS